/*
    Invtro for Inércia Demoparty 2010

    http://creativecommons.org/licenses/by-nc-sa/2.5/
    
    Victor Martins
    www.pixelnerve.com
    
    Out main app.
*/

import crayolon.portamod.*; 

import javax.media.opengl.*;
import processing.opengl.*;
import vitamin.*;
import vitamin.math.*;
import vitamin.fx.*;

import java.awt.event.*;
import javax.swing.*;
import javax.media.opengl.glu.*; 
import com.sun.opengl.util.*;
//import com.sun.opengl.util.FPSAnimator;    


boolean USE_PROCESSING = false;


boolean isFullScreen = true;
int NUM_SAMPLES = 8;
int WIDTH = 800;     //1280;
int HEIGHT = 450;    //720;
float aspectRatio = WIDTH/(float)HEIGHT; 


boolean renderToVideo = false;
int frameCounter = 0;

PortaMod mymod; 


PImage p;
PImage pflip;


VTimer timer;
VGL vgl;
EffectManager fxMan;
CustomScene scene;
VCamera cam; 
VTextRenderer textRender;  

String[] textStrings;

ArrayList _colors;
//ArrayList _bubbleTex;

Color4 currActiveColor;


///___________________________________________________________
void setup()
{
    if( USE_PROCESSING )
    {
        size( WIDTH, HEIGHT, OPENGL );
        hint( ENABLE_OPENGL_4X_SMOOTH ); 
//        hint( DISABLE_OPENGL_ERROR_REPORT ); 
    }
    //else size( 100, 100, OPENGL );
  
    frameRate( 1000 ); 
    
    randomSeed( millis() );
    
    if( !USE_PROCESSING ) noLoop();

    // Init demo
    if( !USE_PROCESSING )
    {
        println( "Init window (demo)" );
        initDemo();     
    }
    else
    {
        initApp();
    }
}


void initApp()
{
    aspectRatio = WIDTH / (float)HEIGHT; 

    if( USE_PROCESSING )
    {
        vgl = new VGL( this );
        vgl.setVSync( true );
    }
  
    mymod = new PortaMod(this); 
    mymod.doModLoad( "ne7-yes_mama.xm", false, 6.020f ); 
//    mymod.loopSong();
    println( "looping: " + mymod.looping );

    cam = new VCamera( this, 0, 100, 200, 0, 100, 0, 0, 1, 0 ); 
//    cam.setToCenter();
  
    textRender = new VTextRenderer( WIDTH, HEIGHT, "Arial Bold", 32, true, true );   
    textRender.setColor( 1, 1, 1, 0.75 ); 
    
    textStrings = loadStrings( "text.txt" );
    textStrings[0] = " ";
  
//    fxMan = new EffectManager( vgl.gl() );
  
    scene = new CustomScene();
    scene.Init( vgl.gl() );


//  fxMan.AddEffect( scene );
  
    // Process all effects now!
//  fxMan.process();

    float r = 1.0 / 255.0;
    _colors = new ArrayList();
    _colors.add( new Color4(1, 1, 1, 1) );

/*    _colors.add( new Color4(175*r, 90*r, 113*r, 1) );
    _colors.add( new Color4(253*r, 135*r, 159*r, 1) );
    _colors.add( new Color4(40*r, 30*r, 54*r, 1) );
    _colors.add( new Color4(29*r, 22*r, 64*r, 1) );
    _colors.add( new Color4(255*r, 213*r, 221*r, 1) );*/
    _colors.add( new Color4(226*r, 223*r, 154*r, 1) );
    _colors.add( new Color4(235*r, 229*r, 77*r, 1) );
    _colors.add( new Color4(117*r, 116*r, 73*r, 1) );
    //_colors.add( new Color4(75*r, 73*r, 11*r, 1) );
    _colors.add( new Color4(255*r, 0*r, 81*r, 1) );

    currActiveColor = (Color4)_colors.get( 0 );
  
    if( !renderToVideo ) mymod.play();
    
    
    if( renderToVideo )
    {
        p = new PImage();
        p = createImage( WIDTH, HEIGHT, RGB );
        pflip = new PImage();
        pflip = createImage( WIDTH, HEIGHT, RGB );
    }

    if( renderToVideo )    timer = new VTimer( VTimer.OFFLINE, 60 );
    else    timer = new VTimer();
    timer.start();
}


void draw()
{
    if( USE_PROCESSING ) drawP5();
}


///___________________________________________________________
void drawP5()
{
//    println( frameRate + ", numOfSeeds: " + scene._seeds.size() );
    float time = timer.getCurrTime();
    timer.update();

    vgl.begin();
    vgl.background( 0.85 );

    scene.Render( time );
    scene.Update( time );


    vgl.ortho( WIDTH, HEIGHT );
    // Fade in
    vgl.enableTexture( false );
    float fadeOutTime = (60+32)-4;
    if( time < fadeOutTime ) vgl.fill( 0, 1-MathUtils.clamp(time*0.2, 0, 1) );
    else vgl.fill( 0, MathUtils.clamp((time-fadeOutTime)*0.25, 0, 1) );
    vgl.rectTopLeft( WIDTH, HEIGHT );


    vgl.end();


    //
    // Offline rendering
    //
    if( renderToVideo )
    {
//            save( sketchPath("SEQ/frame"+nf(frameCounter,7)+".png") );
        p.pixels = vgl.readPixels( 0, 0, WIDTH, HEIGHT, SurfaceFormat.RGBA );
        p = flipImageVertical( p );
        p.save( sketchPath("SEQ/frame"+nf(frameCounter,7)+".png") );

        frameCounter++;
        if( frameCounter%30 == 0 ) println( "count: " + frameCounter );

        if( time > 60+32 ) System.exit( 0 );
    }
    
    if( !renderToVideo && !mymod.playing ) System.exit( 0 );

  
    //
    // Update Camera
    //
//    updateCamera( 10.0 );
}



PImage flipImageVertical( PImage img )
{
    int w = img.width;
    int h = img.height;
    
    PImage tmp = new PImage();
    tmp = createImage( w, h, RGB );
    int[] temp = new int[ w*h ];
    
    System.arraycopy( img.pixels, 0, temp, 0, w*h );

    tmp.loadPixels();
    for( int j=0; j<h; j++ )
    {
      for( int i=0; i<w; i++ )
      {
        tmp.pixels[i+j*w] = temp[i+((h-1)-j)*w];
      }
    }  
    tmp.updatePixels();
 
    return tmp;   
}


/*
void keyPressed()
{
    switch( key )
    {
        case 'm':
            scene._showCenter = !scene._showCenter;
            break;
        case ' ':
            scene._doUpdate = !scene._doUpdate;
            break;
        case 'c':
        {
            println( "CamPos: " + cam.getPosition().toString() );
            println( "CamTarget: " + cam.getTarget().toString() );
            println( "CamRight: " + cam.getRight().toString() );
            break;
        }
        case 's':
            save( "frame_"+frameCount+".png" );
            break;
    }
}*/



///___________________________________________________________
void stop()
{
//    scene.Release();  
//    vgl.release();
  
    super.stop();
}
